image.png

image.png

In [2]:
lst = [1, "s", True]
lst
Out[2]:
[1, 's', True]
In [3]:
id(lst)
Out[3]:
2187405640832
In [4]:
id(lst[0])
Out[4]:
2187323703536
In [5]:
id(lst[1])
Out[5]:
2187324525680
In [ ]:
# !pip install numpy
In [6]:
import numpy as np
In [8]:
lst = [1, 2, 3, 4, 5]
lst
Out[8]:
[1, 2, 3, 4, 5]
In [26]:
arr = np.array([1, 2, 3, 4, 5])
arr
Out[26]:
array([1, 2, 3, 4, 5])
In [11]:
type(arr)
Out[11]:
numpy.ndarray
In [12]:
arr.dtype
Out[12]:
dtype('int32')
In [27]:
arr = np.array(lst, dtype=np.float16)
arr
Out[27]:
array([1., 2., 3., 4., 5.], dtype=float16)
In [28]:
arr = np.array(lst)
arr.dtype
Out[28]:
dtype('int32')
In [32]:
arr.astype(np.float32)
Out[32]:
array([1., 2., 3., 4., 5.], dtype=float32)
In [31]:
arr_new = arr.astype(np.float32)
arr_new.dtype
Out[31]:
dtype('float32')
In [30]:
arr.dtype
Out[30]:
dtype('int32')
In [33]:
for i in lst:
    print(i)
1
2
3
4
5
In [34]:
for i in arr:
    print(i)
1
2
3
4
5

image.png

image.png

In [46]:
lst = [7, 2, 9, 10]
arr = np.array([7, 2, 9, 10])
arr
Out[46]:
array([ 7,  2,  9, 10])
In [47]:
arr.shape
Out[47]:
(4,)
In [48]:
arr.ndim
Out[48]:
1
In [49]:
lst = [
    [7, 2, 9, 10]
]
arr = np.array(lst)
arr
Out[49]:
array([[ 7,  2,  9, 10]])
In [50]:
arr.ndim
Out[50]:
2
In [51]:
arr.shape
Out[51]:
(1, 4)
In [53]:
lst = [[[7, 2, 9, 10]]]
arr = np.array(lst)
print(arr)
print(arr.shape)
print(arr.ndim)
[[[ 7  2  9 10]]]
(1, 1, 4)
3
In [58]:
lst = [[[[7], [2], [9], [10]]]]
arr = np.array(lst)
print(arr)
print(arr.shape)
print(arr.ndim)
[[[[ 7]
   [ 2]
   [ 9]
   [10]]]]
(1, 1, 4, 1)
4
In [44]:
lst = [
    [5, 3, 4], 
    [9, 0, 1]
]

arr = np.array( [
    [5, 3, 4], 
    [9, 0, 1]
])
arr
Out[44]:
array([[5, 3, 4],
       [9, 0, 1]])
In [40]:
arr.shape
Out[40]:
(2, 3)
In [45]:
arr.ndim
Out[45]:
2
In [59]:
lst = [
    [[5, 3, 4], [9, 1, 3]],
    [[5, 3, 4], [9, 1, 3]],
    [[5, 3, 4], [9, 1, 3]],
    [[5, 3, 4], [9, 1, 3]]
]
arr = np.array(lst)

print(arr.shape)
arr
(4, 2, 3)
Out[59]:
array([[[5, 3, 4],
        [9, 1, 3]],

       [[5, 3, 4],
        [9, 1, 3]],

       [[5, 3, 4],
        [9, 1, 3]],

       [[5, 3, 4],
        [9, 1, 3]]])

Indexing¶

In [84]:
# arr[0, :, :]
arr[0, 0]
Out[84]:
array([5, 3, 4])
In [61]:
arr[0].shape
Out[61]:
(2, 3)
In [78]:
arr[:2, :, :]
Out[78]:
array([[[5, 3, 4],
        [9, 1, 3]],

       [[5, 3, 4],
        [9, 1, 3]]])
In [71]:
arr[:, :, 1]
Out[71]:
array([[3, 1],
       [3, 1],
       [3, 1],
       [3, 1]])
In [79]:
arr[0][0][0]
Out[79]:
5
In [80]:
arr[0,0,0]
Out[80]:
5

Append Item¶

In [85]:
lst = [1, 2, 3, 4, 5]
lst
Out[85]:
[1, 2, 3, 4, 5]
In [86]:
lst.append(10)
lst
Out[86]:
[1, 2, 3, 4, 5, 10]
In [90]:
arr = np.array([1, 2, 3, 4, 5])
arr = np.append(arr, [10])   # It flattens then appends
arr
Out[90]:
array([ 1,  2,  3,  4,  5, 10])
In [97]:
arr = np.arange(24).reshape(2, 3, 4)
print(arr)
arr.shape
[[[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11]]

 [[12 13 14 15]
  [16 17 18 19]
  [20 21 22 23]]]
Out[97]:
(2, 3, 4)
In [98]:
arr = np.append(arr, [10])
arr
Out[98]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23, 10])
In [94]:
# arr.flatten()
Out[94]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23])
In [100]:
list(range(24))
Out[100]:
[0,
 1,
 2,
 3,
 4,
 5,
 6,
 7,
 8,
 9,
 10,
 11,
 12,
 13,
 14,
 15,
 16,
 17,
 18,
 19,
 20,
 21,
 22,
 23]
In [101]:
np.array(list(range(24)))
Out[101]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23])
In [102]:
np.arange(24)
Out[102]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23])
In [ ]:
np.array([0, 1, 2, 3, 4, 5, 6, , , 23])

Reshape¶

In [103]:
arr = np.arange(24)
arr
Out[103]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23])
In [104]:
arr.shape
Out[104]:
(24,)
In [105]:
arr.reshape(1, 24)
Out[105]:
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
        16, 17, 18, 19, 20, 21, 22, 23]])
In [108]:
arr.reshape(1, 1, 24)
Out[108]:
array([[[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
         16, 17, 18, 19, 20, 21, 22, 23]]])
In [110]:
arr.reshape(6, 4)
Out[110]:
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15],
       [16, 17, 18, 19],
       [20, 21, 22, 23]])
In [113]:
arr.reshape(6, 4, 1)
Out[113]:
array([[[ 0],
        [ 1],
        [ 2],
        [ 3]],

       [[ 4],
        [ 5],
        [ 6],
        [ 7]],

       [[ 8],
        [ 9],
        [10],
        [11]],

       [[12],
        [13],
        [14],
        [15]],

       [[16],
        [17],
        [18],
        [19]],

       [[20],
        [21],
        [22],
        [23]]])
In [114]:
arr.reshape(3, 8)
Out[114]:
array([[ 0,  1,  2,  3,  4,  5,  6,  7],
       [ 8,  9, 10, 11, 12, 13, 14, 15],
       [16, 17, 18, 19, 20, 21, 22, 23]])
In [115]:
arr.reshape(1, 3, 8)
Out[115]:
array([[[ 0,  1,  2,  3,  4,  5,  6,  7],
        [ 8,  9, 10, 11, 12, 13, 14, 15],
        [16, 17, 18, 19, 20, 21, 22, 23]]])
In [116]:
arr.reshape(5, 8)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[116], line 1
----> 1 arr.reshape(5, 8)

ValueError: cannot reshape array of size 24 into shape (5,8)
In [117]:
arr.reshape(-1, 8)
Out[117]:
array([[ 0,  1,  2,  3,  4,  5,  6,  7],
       [ 8,  9, 10, 11, 12, 13, 14, 15],
       [16, 17, 18, 19, 20, 21, 22, 23]])
In [118]:
arr.reshape(3, -1, 2)
Out[118]:
array([[[ 0,  1],
        [ 2,  3],
        [ 4,  5],
        [ 6,  7]],

       [[ 8,  9],
        [10, 11],
        [12, 13],
        [14, 15]],

       [[16, 17],
        [18, 19],
        [20, 21],
        [22, 23]]])
In [125]:
arr = arr.reshape(3, -1, 2)
arr.shape
Out[125]:
(3, 4, 2)
In [120]:
arr
Out[120]:
array([[[ 0,  1],
        [ 2,  3],
        [ 4,  5],
        [ 6,  7]],

       [[ 8,  9],
        [10, 11],
        [12, 13],
        [14, 15]],

       [[16, 17],
        [18, 19],
        [20, 21],
        [22, 23]]])
In [124]:
arr.reshape(-1)
Out[124]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23])
In [127]:
arr.reshape(-1, 24)
Out[127]:
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
        16, 17, 18, 19, 20, 21, 22, 23]])

Mathematical Operations¶

Element-wise¶

In [136]:
lst1 = [1, 2, 3, 4, 5]
arr1 = np.array(lst1)
arr1
Out[136]:
array([1, 2, 3, 4, 5])
In [137]:
lst2 = [10, 20, 30, 40, 50]
arr2 = np.array(lst2)
arr2
Out[137]:
array([10, 20, 30, 40, 50])
In [138]:
# Vectorization
arr1 + arr2
Out[138]:
array([11, 22, 33, 44, 55])
In [141]:
res = []
for x,y in zip(arr1, arr2):
    res.append(x+y)
    
np.array(res)
Out[141]:
array([11, 22, 33, 44, 55])
In [142]:
arr1
Out[142]:
array([1, 2, 3, 4, 5])
In [140]:
arr1 + 50
Out[140]:
array([51, 52, 53, 54, 55])
In [143]:
arr1 * 50
Out[143]:
array([ 50, 100, 150, 200, 250])
In [144]:
arr1 / 50
Out[144]:
array([0.02, 0.04, 0.06, 0.08, 0.1 ])
In [145]:
arr1 // 50
Out[145]:
array([0, 0, 0, 0, 0], dtype=int32)
In [146]:
arr1 ** 2
Out[146]:
array([ 1,  4,  9, 16, 25])
In [147]:
arr1 ** 0.5
Out[147]:
array([1.        , 1.41421356, 1.73205081, 2.        , 2.23606798])
In [150]:
np.power(arr1, 2)   # arr1**2
Out[150]:
array([ 1,  4,  9, 16, 25], dtype=int32)
In [151]:
np.sqrt(arr1)   # arr1**0.5
Out[151]:
array([1.        , 1.41421356, 1.73205081, 2.        , 2.23606798])
In [152]:
np.log(arr1)
Out[152]:
array([0.        , 0.69314718, 1.09861229, 1.38629436, 1.60943791])
In [153]:
np.exp(arr1)
Out[153]:
array([  2.71828183,   7.3890561 ,  20.08553692,  54.59815003,
       148.4131591 ])
In [154]:
np.sin(arr1)
Out[154]:
array([ 0.84147098,  0.90929743,  0.14112001, -0.7568025 , -0.95892427])
In [155]:
np.deg2rad([90, 180])
Out[155]:
array([1.57079633, 3.14159265])
In [156]:
np.pi
Out[156]:
3.141592653589793

Attributes of NumPy Arrays¶

In [157]:
arr = np.arange(24).reshape(2, 3, 4)
arr
Out[157]:
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]],

       [[12, 13, 14, 15],
        [16, 17, 18, 19],
        [20, 21, 22, 23]]])
In [158]:
arr.shape
Out[158]:
(2, 3, 4)
In [161]:
len(arr.shape) # arr.ndim
Out[161]:
3
In [159]:
arr.ndim
Out[159]:
3
In [162]:
arr.size
Out[162]:
24
In [163]:
arr.dtype
Out[163]:
dtype('int32')
In [166]:
arr.astype('float32')
Out[166]:
array([[[ 0.,  1.,  2.,  3.],
        [ 4.,  5.,  6.,  7.],
        [ 8.,  9., 10., 11.]],

       [[12., 13., 14., 15.],
        [16., 17., 18., 19.],
        [20., 21., 22., 23.]]], dtype=float32)
In [168]:
arr = np.array([1, 2, 30])
arr.shape
Out[168]:
(3,)
In [169]:
len(arr.shape)
Out[169]:
1
In [170]:
arr.size
Out[170]:
3

Array Shape Manipulation¶

image.png

In [173]:
arr = np.arange(24)
arr
Out[173]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23])
In [178]:
arr = arr.reshape(3, 8)
arr
Out[178]:
array([[ 0,  1,  2,  3,  4,  5,  6,  7],
       [ 8,  9, 10, 11, 12, 13, 14, 15],
       [16, 17, 18, 19, 20, 21, 22, 23]])
In [175]:
arr.reshape(-1)
Out[175]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23])
In [176]:
arr.reshape(24)
Out[176]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23])
In [179]:
arr = arr.reshape(3, 8, 1, 1)
In [180]:
arr.ravel()
Out[180]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23])
In [181]:
arr.flatten()
Out[181]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23])

Memory¶

In [184]:
x = 8
y = 8

print(id(x))
print(id(y))
2187323703760
2187323703760
In [185]:
y = 20

print(id(x))
print(id(y))
2187323703760
2187323704144
In [200]:
lst1 = [1, 2, 3]
lst2 = lst1


print(id(lst1))
print(id(lst2))
2187799746048
2187799746048
In [201]:
# Reference Equality
lst1 is lst2
Out[201]:
True
In [202]:
lst1[0] = 50
In [203]:
print(lst1)
print(lst2)
[50, 2, 3]
[50, 2, 3]
In [192]:
lst2 = [3, 3, 3, 3]
In [193]:
lst1[0] = 100
In [194]:
print(lst1)
print(lst2)
[100, 2, 3]
[3, 3, 3, 3]
In [195]:
lst2[0] = 70
In [196]:
lst2
Out[196]:
[70, 3, 3, 3]
In [197]:
x = 5
y = 5

x == y
Out[197]:
True
In [198]:
x = 100
In [199]:
x == y
Out[199]:
False

View vs deep-Copy¶

In [235]:
arr1 = np.random.randn(2, 3)
arr2 = arr1


# Referenece Equality
print(id(arr1))
print(id(arr2))

arr2 is arr1
2187827405488
2187827405488
Out[235]:
True
In [236]:
print(arr1)
[[-0.07320952  0.26433901 -1.3630782 ]
 [ 1.97975398  0.01702801  0.35591298]]
In [238]:
arr1[0] = 5
arr2
Out[238]:
array([[5.        , 5.        , 5.        ],
       [1.97975398, 0.01702801, 0.35591298]])
In [248]:
arr = np.random.randint(0, 100, size=(2, 3))
arr
Out[248]:
array([[74, 69, 25],
       [86,  3,  7]])
In [249]:
arr_view = arr.view().reshape(-1)
arr_view
Out[249]:
array([74, 69, 25, 86,  3,  7])
In [250]:
arr_view[0] = 555
In [252]:
arr_view
Out[252]:
array([555,  69,  25,  86,   3,   7])
In [251]:
arr
Out[251]:
array([[555,  69,  25],
       [ 86,   3,   7]])

Deep Copy¶

In [253]:
arr_deep = np.copy(arr)
arr_deep
Out[253]:
array([[555,  69,  25],
       [ 86,   3,   7]])
In [254]:
print(id(arr))
print(id(arr_deep))
2187827400400
2187827400304
In [255]:
arr[0] = 9999
In [256]:
arr
Out[256]:
array([[9999, 9999, 9999],
       [  86,    3,    7]])
In [257]:
arr_deep
Out[257]:
array([[555,  69,  25],
       [ 86,   3,   7]])

image.png

image.png

Squeeze¶

image.png

In [264]:
arr = np.arange(10).reshape(-1, 2, 1, 5)
arr
Out[264]:
array([[[[0, 1, 2, 3, 4]],

        [[5, 6, 7, 8, 9]]]])
In [265]:
arr.shape
Out[265]:
(1, 2, 1, 5)
In [266]:
arr.squeeze()
Out[266]:
array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]])
In [267]:
arr.squeeze().shape
Out[267]:
(2, 5)
In [268]:
arr = np.arange(10)
arr
Out[268]:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [270]:
a = np.expand_dims(arr, axis=0)
a.shape
Out[270]:
(1, 10)
In [ ]:
# np.array([img])
In [ ]:
# B x H x W x D
# (1, 100, 100, 3)
In [271]:
np.array([[1, 2, 3]]).shape
Out[271]:
(1, 3)
In [272]:
arr = np.array([1, 2, 3])
arr.shape
Out[272]:
(3,)
In [280]:
np.expand_dims(arr, axis=0).shape
Out[280]:
(1, 3)
In [276]:
np.array([arr]).shape
Out[276]:
(1, 3)

Generating Data¶

In [285]:
np.arange(4, 10.01, 2)
Out[285]:
array([ 4.,  6.,  8., 10.])
In [286]:
np.zeros(shape=(3,4))
Out[286]:
array([[0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.]])
In [304]:
img = np.zeros(shape=(100,100,3))
img[:, :, 0] = 1

img
Out[304]:
array([[[1., 0., 0.],
        [1., 0., 0.],
        [1., 0., 0.],
        ...,
        [1., 0., 0.],
        [1., 0., 0.],
        [1., 0., 0.]],

       [[1., 0., 0.],
        [1., 0., 0.],
        [1., 0., 0.],
        ...,
        [1., 0., 0.],
        [1., 0., 0.],
        [1., 0., 0.]],

       [[1., 0., 0.],
        [1., 0., 0.],
        [1., 0., 0.],
        ...,
        [1., 0., 0.],
        [1., 0., 0.],
        [1., 0., 0.]],

       ...,

       [[1., 0., 0.],
        [1., 0., 0.],
        [1., 0., 0.],
        ...,
        [1., 0., 0.],
        [1., 0., 0.],
        [1., 0., 0.]],

       [[1., 0., 0.],
        [1., 0., 0.],
        [1., 0., 0.],
        ...,
        [1., 0., 0.],
        [1., 0., 0.],
        [1., 0., 0.]],

       [[1., 0., 0.],
        [1., 0., 0.],
        [1., 0., 0.],
        ...,
        [1., 0., 0.],
        [1., 0., 0.],
        [1., 0., 0.]]])
In [289]:
img = np.zeros(shape=(100,100,3))
img
Out[289]:
array([[[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.],
        ...,
        [0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]],

       [[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.],
        ...,
        [0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]],

       [[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.],
        ...,
        [0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]],

       ...,

       [[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.],
        ...,
        [0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]],

       [[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.],
        ...,
        [0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]],

       [[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.],
        ...,
        [0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]]])
In [288]:
import matplotlib.pyplot as plt 
In [295]:
img + 0.5
Out[295]:
array([[[0.5, 0.5, 0.5],
        [0.5, 0.5, 0.5],
        [0.5, 0.5, 0.5],
        ...,
        [0.5, 0.5, 0.5],
        [0.5, 0.5, 0.5],
        [0.5, 0.5, 0.5]],

       [[0.5, 0.5, 0.5],
        [0.5, 0.5, 0.5],
        [0.5, 0.5, 0.5],
        ...,
        [0.5, 0.5, 0.5],
        [0.5, 0.5, 0.5],
        [0.5, 0.5, 0.5]],

       [[0.5, 0.5, 0.5],
        [0.5, 0.5, 0.5],
        [0.5, 0.5, 0.5],
        ...,
        [0.5, 0.5, 0.5],
        [0.5, 0.5, 0.5],
        [0.5, 0.5, 0.5]],

       ...,

       [[0.5, 0.5, 0.5],
        [0.5, 0.5, 0.5],
        [0.5, 0.5, 0.5],
        ...,
        [0.5, 0.5, 0.5],
        [0.5, 0.5, 0.5],
        [0.5, 0.5, 0.5]],

       [[0.5, 0.5, 0.5],
        [0.5, 0.5, 0.5],
        [0.5, 0.5, 0.5],
        ...,
        [0.5, 0.5, 0.5],
        [0.5, 0.5, 0.5],
        [0.5, 0.5, 0.5]],

       [[0.5, 0.5, 0.5],
        [0.5, 0.5, 0.5],
        [0.5, 0.5, 0.5],
        ...,
        [0.5, 0.5, 0.5],
        [0.5, 0.5, 0.5],
        [0.5, 0.5, 0.5]]])
In [296]:
plt.imshow(img + 0.5)
Out[296]:
<matplotlib.image.AxesImage at 0x1fd68b32b00>
In [ ]:
img[:, :, 0] = 1
In [301]:
img = np.zeros(shape=(100,100,3))
# img[:, :, 0] = 1
img[:, :, 1] = 1
img[:, :, 2] = 1

plt.imshow(img)
Out[301]:
<matplotlib.image.AxesImage at 0x1fd68c44d00>
In [308]:
arr = np.ones(shape=[100, 100])
arr
Out[308]:
array([[1., 1., 1., ..., 1., 1., 1.],
       [1., 1., 1., ..., 1., 1., 1.],
       [1., 1., 1., ..., 1., 1., 1.],
       ...,
       [1., 1., 1., ..., 1., 1., 1.],
       [1., 1., 1., ..., 1., 1., 1.],
       [1., 1., 1., ..., 1., 1., 1.]])
In [309]:
np.zeros(arr.shape)
Out[309]:
array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]])
In [310]:
np.zeros_like(arr)
Out[310]:
array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]])
In [311]:
np.ones_like(arr)
Out[311]:
array([[1., 1., 1., ..., 1., 1., 1.],
       [1., 1., 1., ..., 1., 1., 1.],
       [1., 1., 1., ..., 1., 1., 1.],
       ...,
       [1., 1., 1., ..., 1., 1., 1.],
       [1., 1., 1., ..., 1., 1., 1.],
       [1., 1., 1., ..., 1., 1., 1.]])
In [313]:
np.ones(shape=[100, 100]) * 50
Out[313]:
array([[50., 50., 50., ..., 50., 50., 50.],
       [50., 50., 50., ..., 50., 50., 50.],
       [50., 50., 50., ..., 50., 50., 50.],
       ...,
       [50., 50., 50., ..., 50., 50., 50.],
       [50., 50., 50., ..., 50., 50., 50.],
       [50., 50., 50., ..., 50., 50., 50.]])
In [315]:
np.eye(5)
Out[315]:
array([[1., 0., 0., 0., 0.],
       [0., 1., 0., 0., 0.],
       [0., 0., 1., 0., 0.],
       [0., 0., 0., 1., 0.],
       [0., 0., 0., 0., 1.]])
In [318]:
np.eye(5, 8)
Out[318]:
array([[1., 0., 0., 0., 0., 0., 0., 0.],
       [0., 1., 0., 0., 0., 0., 0., 0.],
       [0., 0., 1., 0., 0., 0., 0., 0.],
       [0., 0., 0., 1., 0., 0., 0., 0.],
       [0., 0., 0., 0., 1., 0., 0., 0.]])

Linspace¶

np.linspace(0, 100, 4)

In [319]:
np.arange(0, 10, 1)
Out[319]:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [324]:
np.linspace(0, 9, 10)
Out[324]:
array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
In [326]:
np.linspace(0, 1, 11)
Out[326]:
array([0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. ])
In [328]:
np.arange(0, 1.05, 0.1)
Out[328]:
array([0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. ])

Random¶

In [493]:
# Return random floats in the half-open interval [0.0, 1.0)
np.random.random()
Out[493]:
0.5008153452935044
In [494]:
np.random.random(size=(3, 4))
Out[494]:
array([[0.64925109, 0.58245294, 0.97262966, 0.78429056],
       [0.2209591 , 0.55783465, 0.1886229 , 0.8964357 ],
       [0.52853941, 0.65390786, 0.30126855, 0.35649155]])
In [533]:
np.random.rand(3, 4)
Out[533]:
array([[0.74224086, 0.23283405, 0.52820927, 0.09909223],
       [0.35562799, 0.07113241, 0.49367314, 0.23931673],
       [0.27010681, 0.14673219, 0.07633481, 0.48630191]])
In [580]:
# from `low` (inclusive) to `high` (exclusive).
np.random.randint(0, 10)
Out[580]:
7
In [594]:
np.random.randint(0, 10, (3, 4))
Out[594]:
array([[7, 8, 0, 7],
       [2, 4, 9, 9],
       [0, 2, 4, 1]])
In [610]:
# Return a sample (or samples) from the "standard normal" distribution.
np.random.randn(3, 4)
Out[610]:
array([[-0.03770591,  2.63111902, -1.21322968,  0.17210536],
       [ 0.087345  , -0.49916868,  0.59380472, -0.14034652],
       [ 1.23123313,  1.00723379,  0.55213194, -1.32125358]])
In [611]:
# Pseudo-random
In [698]:
np.random.seed(1)
np.random.randn(3, 4)
Out[698]:
array([[ 1.62434536, -0.61175641, -0.52817175, -1.07296862],
       [ 0.86540763, -2.3015387 ,  1.74481176, -0.7612069 ],
       [ 0.3190391 , -0.24937038,  1.46210794, -2.06014071]])
In [696]:
np.random.randn(3, 4)
Out[696]:
array([[ 0.79103195, -0.90938745,  1.40279431, -1.40185106],
       [ 0.58685709,  2.19045563, -0.99053633, -0.56629773],
       [ 0.09965137, -0.50347565, -1.55066343,  0.06856297]])

Statistics operations¶

In [699]:
arr = np.random.random((8, 3))
arr
Out[699]:
array([[0.14038694, 0.19810149, 0.80074457],
       [0.96826158, 0.31342418, 0.69232262],
       [0.87638915, 0.89460666, 0.08504421],
       [0.03905478, 0.16983042, 0.8781425 ],
       [0.09834683, 0.42110763, 0.95788953],
       [0.53316528, 0.69187711, 0.31551563],
       [0.68650093, 0.83462567, 0.01828828],
       [0.75014431, 0.98886109, 0.74816565]])
In [700]:
arr.mean()
Out[700]:
0.5458665438905308
In [701]:
arr.mean(axis=0)
Out[701]:
array([0.51153123, 0.56405428, 0.56201412])
In [702]:
arr.mean(axis=1)
Out[702]:
array([0.37974433, 0.65800279, 0.61868001, 0.36234257, 0.492448  ,
       0.51351934, 0.51313829, 0.82905702])
In [703]:
np.mean(arr, axis=1)
Out[703]:
array([0.37974433, 0.65800279, 0.61868001, 0.36234257, 0.492448  ,
       0.51351934, 0.51313829, 0.82905702])
In [ ]:
np.max()
In [704]:
np.median(arr, axis=1)
Out[704]:
array([0.19810149, 0.69232262, 0.87638915, 0.16983042, 0.42110763,
       0.53316528, 0.68650093, 0.75014431])
In [705]:
arr.median
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[705], line 1
----> 1 arr.median

AttributeError: 'numpy.ndarray' object has no attribute 'median'
In [706]:
arr.max()
Out[706]:
0.9888610889064947
In [707]:
arr.max(axis=0)
Out[707]:
array([0.96826158, 0.98886109, 0.95788953])
In [708]:
arr.max(axis=1)
Out[708]:
array([0.80074457, 0.96826158, 0.89460666, 0.8781425 , 0.95788953,
       0.69187711, 0.83462567, 0.98886109])
In [709]:
arr.min(axis=1)
Out[709]:
array([0.14038694, 0.31342418, 0.08504421, 0.03905478, 0.09834683,
       0.31551563, 0.01828828, 0.74816565])
In [711]:
arr.std(axis=0)
Out[711]:
array([0.34667095, 0.30656491, 0.34445228])
In [712]:
arr.var(axis=0)
Out[712]:
array([0.12018075, 0.09398204, 0.11864738])
In [713]:
arr.std(axis=0)**2
Out[713]:
array([0.12018075, 0.09398204, 0.11864738])
In [715]:
arr = np.array([5, 6, 1, 3, 2, 4])
arr
Out[715]:
array([5, 6, 1, 3, 2, 4])
In [716]:
np.sort(arr)
Out[716]:
array([1, 2, 3, 4, 5, 6])
In [720]:
# Inplace Sorting
arr.sort()
arr
Out[720]:
array([1, 2, 3, 4, 5, 6])
In [ ]:
 
In [ ]:
 
In [727]:
arr = np.array([5, 6, 1, 3, 2, 4])*10
arr
Out[727]:
array([50, 60, 10, 30, 20, 40])
In [728]:
idx = np.argsort(arr)
idx
Out[728]:
array([2, 4, 3, 5, 0, 1], dtype=int64)
In [729]:
arr[idx]
Out[729]:
array([10, 20, 30, 40, 50, 60])
In [733]:
arr[[0, 1, 3]]
Out[733]:
array([50, 60, 30])
In [734]:
np.max(arr)
Out[734]:
60
In [735]:
np.argmax(arr)
Out[735]:
1

Indexing and Slicing¶

In [740]:
arr = np.arange(12).reshape(3, 4)
arr
Out[740]:
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
In [741]:
arr[0, 0]
Out[741]:
0
In [742]:
arr[1, 1]
Out[742]:
5
In [743]:
arr[(0, 1), (0, 1)]
Out[743]:
array([0, 5])
In [744]:
arr[(0, 1), (0, 1)] = 100
arr
Out[744]:
array([[100,   1,   2,   3],
       [  4, 100,   6,   7],
       [  8,   9,  10,  11]])
In [745]:
arr[1][2]
Out[745]:
6
In [746]:
# The same
arr[1,2]
Out[746]:
6
In [747]:
arr[:, :]
Out[747]:
array([[100,   1,   2,   3],
       [  4, 100,   6,   7],
       [  8,   9,  10,  11]])
In [748]:
# The same
arr
Out[748]:
array([[100,   1,   2,   3],
       [  4, 100,   6,   7],
       [  8,   9,  10,  11]])
In [749]:
arr[0, :]  # 1st row
arr[0] 
Out[749]:
array([100,   1,   2,   3])
In [751]:
arr[:, 0]  # 1st col 
Out[751]:
array([100,   4,   8])
In [755]:
arr[:, 3]
arr[:, -1]
Out[755]:
array([ 3,  7, 11])
In [758]:
arr[0:2, 0:2]
arr[:2, :2]
Out[758]:
array([[100,   1],
       [  4, 100]])

image.png

Boolean Mask Arrays¶

In [765]:
arr = np.arange(13)
arr
Out[765]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12])
In [766]:
arr[::2]
Out[766]:
array([ 0,  2,  4,  6,  8, 10, 12])
In [771]:
mask = arr % 2  == 0
mask
Out[771]:
array([ True, False,  True, False,  True, False,  True, False,  True,
       False,  True, False,  True])
In [775]:
arr.shape
Out[775]:
(13,)
In [776]:
mask.shape
Out[776]:
(13,)
In [772]:
arr[mask]
Out[772]:
array([ 0,  2,  4,  6,  8, 10, 12])
In [777]:
arr[arr%2==0]
Out[777]:
array([ 0,  2,  4,  6,  8, 10, 12])
In [778]:
arr[arr%2!=0]
Out[778]:
array([ 1,  3,  5,  7,  9, 11])
In [780]:
mask.dtype
Out[780]:
dtype('bool')
In [781]:
mask.shape
Out[781]:
(13,)
In [783]:
mask
Out[783]:
array([ True, False,  True, False,  True, False,  True, False,  True,
       False,  True, False,  True])
In [782]:
np.count_nonzero(mask)
Out[782]:
7
In [784]:
np.sum(mask)
Out[784]:
7
In [785]:
mask.astype('int')
Out[785]:
array([1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1])

Matrix Operations¶

elementwise operations¶

In [786]:
mat_1 = np.array(range(10, 14))
mat_1 = np.reshape(mat_1, (2, 2))
mat_1
Out[786]:
array([[10, 11],
       [12, 13]])
In [787]:
mat_2 = np.array(range(30, 34))
mat_2 = np.reshape(mat_2, (2, 2))
mat_2
Out[787]:
array([[30, 31],
       [32, 33]])
In [788]:
mat_1 + mat_2
Out[788]:
array([[40, 42],
       [44, 46]])
In [789]:
mat_1 - mat_2
Out[789]:
array([[-20, -20],
       [-20, -20]])
In [790]:
mat_1 * mat_2 # elementwise multiplication
Out[790]:
array([[300, 341],
       [384, 429]])
In [791]:
mat_1 / mat_2
Out[791]:
array([[0.33333333, 0.35483871],
       [0.375     , 0.39393939]])
In [792]:
mat_1 % mat_2
Out[792]:
array([[10, 11],
       [12, 13]])

scaler operations¶

In [796]:
5 * mat_1
Out[796]:
array([[50, 55],
       [60, 65]])

dot product¶

In [809]:
mat_1 = np.array([[2, 4], [7, 8], [3, 2]])
mat_1
Out[809]:
array([[2, 4],
       [7, 8],
       [3, 2]])
In [810]:
mat_2 = np.array([[1, 3], [4, 7]])
mat_2
Out[810]:
array([[1, 3],
       [4, 7]])
In [811]:
np.dot(mat_1, mat_2)  # 3x2 
Out[811]:
array([[18, 34],
       [39, 77],
       [11, 23]])
In [812]:
mat_1.dot(mat_2)   # 3x2 
Out[812]:
array([[18, 34],
       [39, 77],
       [11, 23]])
In [813]:
mat_1 @ mat_2  # 3x2 
Out[813]:
array([[18, 34],
       [39, 77],
       [11, 23]])
In [815]:
np.matmul(mat_1, mat_2)
Out[815]:
array([[18, 34],
       [39, 77],
       [11, 23]])
In [814]:
mat_1 * mat_2   # Element wise Multiplication
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[814], line 1
----> 1 mat_1 * mat_2

ValueError: operands could not be broadcast together with shapes (3,2) (2,2) 

matrix transpose¶

In [816]:
mat_1
Out[816]:
array([[2, 4],
       [7, 8],
       [3, 2]])
In [817]:
mat_1.T
Out[817]:
array([[2, 7, 3],
       [4, 8, 2]])
In [818]:
mat_1.transpose()
Out[818]:
array([[2, 7, 3],
       [4, 8, 2]])
In [824]:
vec_1 = np.array([1, 2])
vec_2 = np.array([3, 4])

print(vec_1.shape)
print(vec_2.shape)

vec_1 @ vec_2
(2,)
(2,)
Out[824]:
11
In [821]:
vec_1 = np.array([[1, 2]])   # row
vec_2 = np.array([[3], [4]]) # col

print(vec_1.shape)
print(vec_2.shape)

vec_1 @ vec_2
(1, 2)
(2, 1)
Out[821]:
array([[11]])
In [826]:
vec_1 = np.array([[1, 2]])   # row
vec_2 = np.array([[3, 4]]) # row

print(vec_1.shape)
print(vec_2.shape)

vec_1 @ vec_2
(1, 2)
(1, 2)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[826], line 7
      4 print(vec_1.shape)
      5 print(vec_2.shape)
----> 7 vec_1 @ vec_2

ValueError: matmul: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (n?,k),(k,m?)->(n?,m?) (size 1 is different from 2)
In [827]:
vec_1 = np.array([[1, 2]])   # row
vec_2 = np.array([[3, 4]]) # row

print(vec_1.shape)
print(vec_2.shape)

vec_1 @ vec_2.T
(1, 2)
(1, 2)
Out[827]:
array([[11]])

Meshgrid¶

x = np.linspace(-3, 3, 5)
    y = np.linspace(-3, 3, 5)

    xx, yy = np.meshgrid(x, y)

    plt.scatter(xx, yy)

In [828]:
x = np.linspace(-3, 3, 5)
y = np.linspace(-3, 3, 5)

print(x)
print(y)
[-3.  -1.5  0.   1.5  3. ]
[-3.  -1.5  0.   1.5  3. ]
In [829]:
plt.scatter(x, y)
Out[829]:
<matplotlib.collections.PathCollection at 0x1fd690e5d80>
In [830]:
xx, yy = np.meshgrid(x, y)

print(xx)
print('-'*30)
print(yy)
[[-3.  -1.5  0.   1.5  3. ]
 [-3.  -1.5  0.   1.5  3. ]
 [-3.  -1.5  0.   1.5  3. ]
 [-3.  -1.5  0.   1.5  3. ]
 [-3.  -1.5  0.   1.5  3. ]]
------------------------------
[[-3.  -3.  -3.  -3.  -3. ]
 [-1.5 -1.5 -1.5 -1.5 -1.5]
 [ 0.   0.   0.   0.   0. ]
 [ 1.5  1.5  1.5  1.5  1.5]
 [ 3.   3.   3.   3.   3. ]]
In [831]:
plt.scatter(xx, yy);

Stacking¶

In [832]:
arr_1 = np.array([[0, 2], [7, 6]])
arr_2 = np.array([[3, 7], [1, 4]])

np.vstack([arr_1, arr_2])
Out[832]:
array([[0, 2],
       [7, 6],
       [3, 7],
       [1, 4]])
In [833]:
np.hstack([arr_1, arr_2])
Out[833]:
array([[0, 2, 3, 7],
       [7, 6, 1, 4]])

image.png

In [839]:
# Scalar
np.array(1000).shape
Out[839]:
()

image.png

In [840]:
a = np.array([1, 2])
b = np.array([3, 4])
In [848]:
# np.sum(a * b)
In [841]:
print(a.dot(b))
print(np.dot(a, b))
11
11
In [843]:
result = 0
for i in range(len(a)):
    result += a[i] * b[i]
    
result
Out[843]:
11
In [845]:
# Vectorization
a @ b
Out[845]:
11
In [850]:
# using For-loop
def slow_dot_product(a, b):
    result = 0
    for i in range(len(a)):
        result += a[i] * b[i]
    return result

slow_dot_product(a, b)
Out[850]:
11
In [854]:
import time
In [858]:
a = np.random.randn(10000)
b = np.random.randn(10000)
In [863]:
tic = time.process_time()

for _ in range(10000):
    slow_dot_product(a, b)

toc = time.process_time()


dt1 = toc - tic
print("Time in sec:", dt1)
Time in sec: 28.625
In [862]:
tic = time.process_time()

for _ in range(10000):
    a @ b

toc = time.process_time()


dt1 = toc - tic
print("Time in sec:", dt1)
Time in sec: 0.03125
In [864]:
28.625 / 0.03125
Out[864]:
916.0

image.png

In [865]:
arr = np.array([3, 4])
np.linalg.norm(arr)
Out[865]:
5.0

image.png

In [868]:
np.sqrt(arr.dot(arr))
Out[868]:
5.0

image.png

Linear Algebra¶

In [869]:
arr = np.array([1, 2, 3, 4])
arr
Out[869]:
array([1, 2, 3, 4])
In [872]:
arr.T
Out[872]:
array([1, 2, 3, 4])
In [873]:
arr.dot(arr)
Out[873]:
30
In [874]:
arr = np.arange(9).reshape(3, 3)
arr
Out[874]:
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
In [875]:
np.linalg.det(arr)
Out[875]:
0.0
In [876]:
np.linalg.inv(arr)
---------------------------------------------------------------------------
LinAlgError                               Traceback (most recent call last)
Cell In[876], line 1
----> 1 np.linalg.inv(arr)

File <__array_function__ internals>:180, in inv(*args, **kwargs)

File ~\anaconda3\lib\site-packages\numpy\linalg\linalg.py:552, in inv(a)
    550 signature = 'D->D' if isComplexType(t) else 'd->d'
    551 extobj = get_linalg_error_extobj(_raise_linalgerror_singular)
--> 552 ainv = _umath_linalg.inv(a, signature=signature, extobj=extobj)
    553 return wrap(ainv.astype(result_t, copy=False))

File ~\anaconda3\lib\site-packages\numpy\linalg\linalg.py:89, in _raise_linalgerror_singular(err, flag)
     88 def _raise_linalgerror_singular(err, flag):
---> 89     raise LinAlgError("Singular matrix")

LinAlgError: Singular matrix
In [878]:
arr = np.random.randn(9).reshape(3, 3)
arr
Out[878]:
array([[ 0.49195809,  0.10653615,  0.26540123],
       [-0.80789976, -1.12249299, -0.13511416],
       [-1.29134445,  0.61970383, -0.33890938]])
In [879]:
np.linalg.det(arr)
Out[879]:
-0.29981854353410736
In [880]:
np.linalg.inv(arr)
Out[880]:
array([[-1.54811692, -0.66899216, -0.94562689],
       [ 0.33128668, -0.58700569,  0.49345542],
       [ 6.50454654,  1.47570316,  1.55477035]])
In [882]:
vec = np.array([1, 2, 3])
arr = np.diag(vec)
arr
Out[882]:
array([[1, 0, 0],
       [0, 2, 0],
       [0, 0, 3]])
In [883]:
np.diag(arr)
Out[883]:
array([1, 2, 3])
In [884]:
np.trace(arr)
Out[884]:
6

image.png

In [885]:
np.linalg.eig(arr)
Out[885]:
(array([1., 2., 3.]),
 array([[1., 0., 0.],
        [0., 1., 0.],
        [0., 0., 1.]]))
In [887]:
eig_values, eig_vectors = np.linalg.eig(arr)
In [888]:
eig_values
Out[888]:
array([1., 2., 3.])
In [889]:
eig_vectors
Out[889]:
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])
In [893]:
# arrays comparisonsarr1 = np.array([1, 2, 3])
arr1 = np.array([1, 2.00000001, 3])
arr2 = np.array([1, 2, 3])

np.allclose(arr1, arr2)
Out[893]:
True
In [892]:
# Element-wise Comparison
arr1 == arr2
Out[892]:
array([ True,  True,  True])

Solving Linear Systems¶

image.png

image.png

In [894]:
A = np.array([[1, 1], [1.5, 4]])
b = np.array([2200, 5050])
In [895]:
np.linalg.inv(A) @  b
Out[895]:
array([1500.,  700.])

image.png

In [896]:
np.linalg.solve(A, b)
Out[896]:
array([1500.,  700.])

Tiling Arrays¶

In [897]:
arr = np.array(np.arange(6))
arr
Out[897]:
array([0, 1, 2, 3, 4, 5])
In [898]:
np.tile(arr, 3)
Out[898]:
array([0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5])
In [899]:
np.repeat(arr, 3)
Out[899]:
array([0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5])
In [900]:
np.tile(arr, (3, 2))
Out[900]:
array([[0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5],
       [0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5],
       [0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5]])

Read+Write a simple Dataset.ipynb¶

In [902]:
arr = np.genfromtxt("simple_dataset_to_read.csv", delimiter='|')
arr 
Out[902]:
array([[ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10.],
       [ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11.],
       [ 2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11., 12.],
       [ 3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11., 12., 13.],
       [ 4.,  5.,  6.,  7.,  8.,  9., 10., 11., 12., 13., 14.],
       [ 5.,  6.,  7.,  8.,  9., 10., 11., 12., 13., 14., 15.],
       [ 6.,  7.,  8.,  9., 10., 11., 12., 13., 14., 15., 16.],
       [ 7.,  8.,  9., 10., 11., 12., 13., 14., 15., 16., 17.],
       [ 8.,  9., 10., 11., 12., 13., 14., 15., 16., 17., 18.],
       [ 9., 10., 11., 12., 13., 14., 15., 16., 17., 18., 19.],
       [10., 11., 12., 13., 14., 15., 16., 17., 18., 19., 20.]])
In [903]:
new_arr = arr / 50 
new_arr
Out[903]:
array([[0.  , 0.02, 0.04, 0.06, 0.08, 0.1 , 0.12, 0.14, 0.16, 0.18, 0.2 ],
       [0.02, 0.04, 0.06, 0.08, 0.1 , 0.12, 0.14, 0.16, 0.18, 0.2 , 0.22],
       [0.04, 0.06, 0.08, 0.1 , 0.12, 0.14, 0.16, 0.18, 0.2 , 0.22, 0.24],
       [0.06, 0.08, 0.1 , 0.12, 0.14, 0.16, 0.18, 0.2 , 0.22, 0.24, 0.26],
       [0.08, 0.1 , 0.12, 0.14, 0.16, 0.18, 0.2 , 0.22, 0.24, 0.26, 0.28],
       [0.1 , 0.12, 0.14, 0.16, 0.18, 0.2 , 0.22, 0.24, 0.26, 0.28, 0.3 ],
       [0.12, 0.14, 0.16, 0.18, 0.2 , 0.22, 0.24, 0.26, 0.28, 0.3 , 0.32],
       [0.14, 0.16, 0.18, 0.2 , 0.22, 0.24, 0.26, 0.28, 0.3 , 0.32, 0.34],
       [0.16, 0.18, 0.2 , 0.22, 0.24, 0.26, 0.28, 0.3 , 0.32, 0.34, 0.36],
       [0.18, 0.2 , 0.22, 0.24, 0.26, 0.28, 0.3 , 0.32, 0.34, 0.36, 0.38],
       [0.2 , 0.22, 0.24, 0.26, 0.28, 0.3 , 0.32, 0.34, 0.36, 0.38, 0.4 ]])
In [904]:
np.savetxt('test_save.csv', new_arr, delimiter=',', fmt='%0.2e')
In [905]:
new_arr
Out[905]:
array([[0.  , 0.02, 0.04, 0.06, 0.08, 0.1 , 0.12, 0.14, 0.16, 0.18, 0.2 ],
       [0.02, 0.04, 0.06, 0.08, 0.1 , 0.12, 0.14, 0.16, 0.18, 0.2 , 0.22],
       [0.04, 0.06, 0.08, 0.1 , 0.12, 0.14, 0.16, 0.18, 0.2 , 0.22, 0.24],
       [0.06, 0.08, 0.1 , 0.12, 0.14, 0.16, 0.18, 0.2 , 0.22, 0.24, 0.26],
       [0.08, 0.1 , 0.12, 0.14, 0.16, 0.18, 0.2 , 0.22, 0.24, 0.26, 0.28],
       [0.1 , 0.12, 0.14, 0.16, 0.18, 0.2 , 0.22, 0.24, 0.26, 0.28, 0.3 ],
       [0.12, 0.14, 0.16, 0.18, 0.2 , 0.22, 0.24, 0.26, 0.28, 0.3 , 0.32],
       [0.14, 0.16, 0.18, 0.2 , 0.22, 0.24, 0.26, 0.28, 0.3 , 0.32, 0.34],
       [0.16, 0.18, 0.2 , 0.22, 0.24, 0.26, 0.28, 0.3 , 0.32, 0.34, 0.36],
       [0.18, 0.2 , 0.22, 0.24, 0.26, 0.28, 0.3 , 0.32, 0.34, 0.36, 0.38],
       [0.2 , 0.22, 0.24, 0.26, 0.28, 0.3 , 0.32, 0.34, 0.36, 0.38, 0.4 ]])

insert / delete¶

In [906]:
arr = np.ones((10, 5))
arr
Out[906]:
array([[1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.]])
In [917]:
new_arr = np.insert(arr, 0, 50, axis=0)
new_arr
Out[917]:
array([[50., 50., 50., 50., 50.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.]])
In [918]:
new_arr
Out[918]:
array([[50., 50., 50., 50., 50.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.]])
In [915]:
np.delete(new_arr, 0, axis=0)
Out[915]:
array([[1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.]])
In [913]:
new_arr[1:]
Out[913]:
array([[1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.]])

Solve Linear Equations in SciPy¶

In [925]:
# Creating input array  
A = np.array([[1, 2, -3], [2, -5, 4], [5, 4, -1]])  
In [926]:
# Solution Array  
b = np.array([[-3], [13], [5]])
In [927]:
from scipy import linalg  
In [928]:
# Solve the linear algebra  
x = linalg.solve(A, b) 
In [929]:
x
Out[929]:
array([[ 2.],
       [-1.],
       [ 1.]])
In [930]:
A.dot(x) - b 
Out[930]:
array([[0.],
       [0.],
       [0.]])
In [932]:
values, vectors = linalg.eig(A)
In [ ]:
# # Sparse Matrix
# [
#     [0, 0, 1, 0, 0, 0, 0]
#     [1, 0, 1, 0, 0, 0, 0]
#     [0, 0, 1, 0, 0, 0, 0]
# ]

image-2.png

image.png

Broadcasting¶

  • Two dimensions NOT equal to each other and not any of them equal ONE --> Error raised
  • Broadcasting is simply a set of rules for applying binary ufuncs (e.g., addition, subtraction, multiplication, etc.) on arrays of different sizes.

Rules of Broadcasting¶

Broadcasting in NumPy follows a strict set of rules to determine the interaction between the two arrays:

  • Rule 1: If the two arrays differ in their number of dimensions, the shape of the one with fewer dimensions is padded with ones on its leading (left) side.
  • Rule 2: If the shape of the two arrays does not match in any dimension, the array with shape equal to 1 in that dimension is stretched to match the other shape.
  • Rule 3: If in any dimension the sizes disagree and neither is equal to 1, an error is raised.

Broadcasting example 1¶

Let's look at adding a two-dimensional array to a one-dimensional array:

Check Dimensions --> (5,) + (2, 5) --> should be the same¶

(1, 5) + (2, 5)

In [933]:
a = np.array([1, 2, 3, 4, 5])                      # (5,)
b = np.array([[0, 0, 0, 0, 0], [5, 5, 5, 5, 5]])   # (2, 5)

print(a.shape)
print(b.shape)

a + b
(5,)
(2, 5)
Out[933]:
array([[ 1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10]])
In [934]:
a = np.array([[1, 2, 3, 4, 5]])                    # (1, 5)
b = np.array([[0, 0, 0, 0, 0], [5, 5, 5, 5, 5]])   # (2, 5)

print(a.shape)
print(b.shape)

a + b
(1, 5)
(2, 5)
Out[934]:
array([[ 1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10]])
In [936]:
# BE CAREFULL
a = np.array([[1], [2], [3], [4], [5]])            # (5, 1)
b = np.array([[0, 0, 0, 0, 0], [5, 5, 5, 5, 5]])   # (2, 5)

print(a.shape)
print(b.shape)

a + b
(5, 1)
(2, 5)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[936], line 8
      5 print(a.shape)
      6 print(b.shape)
----> 8 a + b

ValueError: operands could not be broadcast together with shapes (5,1) (2,5) 
In [937]:
# BE CAREFULL
a = np.array([1, 2, 3, 4, 5])                            # (5,)   -->  (1, 5)
b = np.array([[0, 5], [0, 5], [0, 5], [0, 5], [0, 5]])   # (5, 2) -->  (5, 2)

print(a.shape)
print(b.shape)

a + b
(5,)
(5, 2)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[937], line 8
      5 print(a.shape)
      6 print(b.shape)
----> 8 a + b

ValueError: operands could not be broadcast together with shapes (5,) (5,2) 
Check Shapes --> (1, 5) + (2, 5) --> should be the same broadcasting¶

(2, 5) + (2, 5)

In [939]:
a = np.array([[1, 2, 3, 4, 5]])                    # (1, 5)
b = np.array([[0, 0, 0, 0, 0], [5, 5, 5, 5, 5]])   # (2, 5)

print(a.shape)
print(b.shape)

a + b
(1, 5)
(2, 5)
Out[939]:
array([[ 1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10]])
In [ ]:
 
Check Shapes --> (5, 1) + (1, 5) --> should be the same broadcasting¶

(5, 5) + (5, 5)

In [938]:
a = np.array([[1], [2], [3], [4], [5]])   # (5, 1)
b = np.array([[5, 5, 5, 5, 5]])           # (1, 5)

print(a.shape)
print(b.shape)

a + b
(5, 1)
(1, 5)
Out[938]:
array([[ 6,  6,  6,  6,  6],
       [ 7,  7,  7,  7,  7],
       [ 8,  8,  8,  8,  8],
       [ 9,  9,  9,  9,  9],
       [10, 10, 10, 10, 10]])
Check Shapes --> (1, 5) + (2, 4) --> ERROR¶

ERROR

In [940]:
a = np.array([[1, 2, 3, 4, 5]])   # (1, 5)
b = np.array([[0, 0, 0, 0], [5, 5, 5, 5]])   # (2, 4)

print(a.shape)
print(b.shape)

a + b
(1, 5)
(2, 4)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[940], line 7
      4 print(a.shape)
      5 print(b.shape)
----> 7 a + b

ValueError: operands could not be broadcast together with shapes (1,5) (2,4) 
In [ ]:
 
In [ ]:
 

Q3: Implement the L1 and L2 loss functions¶

Exercise: Implement the numpy vectorized version of the L1 loss. You may find the function abs(x) (absolute value of x) useful.

Reminder:

  • The loss is used to evaluate the performance of your model. The bigger your loss is, the more different your predictions ($ \hat{y} $) are from the true values ($y$). In deep learning, you use optimization algorithms like Gradient Descent to train your model and to minimize the cost.
  • L1 loss is defined as: $$\begin{align*} & L_1(\hat{y}, y) = \sum_{i=0}^m|y^{(i)} - \hat{y}^{(i)}| \end{align*}\tag{6}$$

Expected Output:

L1 1.1
In [707]:
def L1(yhat, y):
    """
    Arguments:
    yhat -- vector of size m (predicted labels)
    y -- vector of size m (true labels)
    
    Returns:
    loss -- the value of the L1 loss function defined above
    """
    
    ### START CODE HERE ### (≈ 1 line of code)
    loss = None
    ### END CODE HERE ###
    
    return loss
In [708]:
yhat = np.array([.9, 0.2, 0.1, .4, .9])
y    = np.array([1 ,  0 ,  0 ,  1, 1])

l1_loss = L1(yhat,y)
print("L1 = " + str(l1_loss))
L1 = 1.1

Exercise: Implement the numpy vectorized version of the L2 loss. There are several way of implementing the L2 loss but you may find the function np.dot() useful. As a reminder, if $x = [x_1, x_2, ..., x_n]$, then np.dot(x,x) = $\sum_{j=0}^n x_j^{2}$.

  • L2 loss is defined as $$\begin{align*} & L_2(\hat{y},y) = \sum_{i=0}^m(y^{(i)} - \hat{y}^{(i)})^2 \end{align*}\tag{7}$$

Expected Output:

L2 0.43
In [704]:
def L2(yhat, y):
    """
    Arguments:
    yhat -- vector of size m (predicted labels)
    y -- vector of size m (true labels)
    
    Returns:
    loss -- the value of the L2 loss function defined above
    """
    
    ### START CODE HERE ### (≈ 1 line of code)
    loss = None
    ### END CODE HERE ###
    
    return loss
In [705]:
yhat = np.array([.9, 0.2, 0.1, .4, .9])
y    = np.array([1 ,  0 ,  0 ,  1, 1])

l2_loss = L2(yhat,y)

print("L2 = " + str(l2_loss))
L2 = 0.43

Q4: comparing the dot product using parallelism in python vs numpy_dot_product vs using the for_loop and compute the time needed for each.¶

In [ ]:
 
In [ ]:
 
In [ ]:
 
In [ ]:
 
In [ ]: